<?php

class ListTemplate {

    protected $mRawData; //Mentahan query data
    protected $mNotExecuteClass = false; //ERROR HANDLER, jika RAW DATA menghasilkan nilai FALSE proses Templatng List tetap dapat dilakukan. Untuk dapat mengeksekusi kelas maka nilai ini harus FALSE.
    protected $mData;
    protected $mTitle;
    protected $mSubtitle;
    protected $mIsFormExec = true;
    protected $mIsSearchable = true;
    protected $mIsFieldNumber = true;
    protected $mIsFieldAction = true;
    protected $mIsTotalRecord = false;
    protected $mIsPageable = true;
    protected $mStatusField;
    protected $mStatus = array();
    protected $mValiditasField;
    protected $mValiditasPattern;
    protected $mValiditasDebug;
    protected $mFieldAlign = array();
    protected $mFieldUCWords = array();
    protected $mFieldClass;
    protected $mFieldHidden = array();
    protected $mCurrentURL;
    protected $mFieldSupport = array();
    //ACTION
    protected $mAddAction = array();
    protected $mEditAction = array();
    protected $mDeleteAction = array();
    protected $mDetailAction = array();
    protected $mUnlockAction = array();
    protected $mResetAction = array();

    public function __construct($pRawData) {
        if (is_object($pRawData)) {
            $mApp = new Application();
            $tFungsi= new Fungsi();
            
            $tFungsi->CalibrateArray($pRawData);
            
            $this->mCurrentURL = $mApp->GetCurrentUrl();
            $this->mRawData = $pRawData;

            $this->mAddAction[Caption] = TEMPLATE_SETTING_LIST_ADD_BUTTON_CAPTION_DEFAULT;

            $this->mAddAction[Auth] = true;
            $this->mEditAction[Auth] = true;
            $this->mDeleteAction[Auth] = true;
            $this->mDetailAction[Auth] = false;
            $this->mUnlockAction[Auth] = false;
            $this->mResetAction[Auth] = false;

            $this->mAddAction[Code] = "add";
            $this->mEditAction[Code] = "edt";
            $this->mDeleteAction[Code] = "del";
            $this->mDetailAction[Code] = "dtl";
            $this->mUnlockAction[Code] = "unl";
            $this->mResetAction[Code] = "rst";
        } else {
            if ($pRawData !== false)
                die();
            else
                $this->mNotExecuteClass = true;
            //ERROR: Bukan merupakan object       
        }
    }



    public function SetSearchableList($pValue) {
        $this->mIsSearchable = $pValue;
    }

    public function SetPageableList($pValue) {
        $this->mIsPageable = $pValue;
    }

    public function SetFieldAction($pBool) {
        if (is_bool($pBool)) {
            $this->mIsFieldAction = $pBool;
        } else {
            //ERROR: PARAMETER HARUS BOOLEAN
        }
    }

    public function SetFormExec($pBool) {
        if (is_bool($pBool)) {
            $this->mIsFormExec = $pBool;
        } else {
            //ERROR: PARAMETER HARUS BOOLEAN
        }
    }

    public function SetFieldSupport($pName, $pValue) {
        $this->mFieldSupport[$pName] = $pValue;
    }



    public function SetStatusField($pIndex) {
        $this->mStatusField = $pIndex;
    }

    public function SetStatus($pValue) {
        $this->mStatus = $pValue;
    }

    public function SetValiditasField($pIndex) {
        $this->mValiditasField = $pIndex;
        $this->SetFieldHidden($pIndex);
    }
    
    protected function GetUCWordsField($tField) {
        $tUCWordsField= array();
        $i = 0;
        
        while ($tField[$i]) {
            if (isset($this->mFieldUCWords[$i])) {
                array_push($tUCWordsField, $tField[$i][FieldName]);
            }
            $i++;
        }
        
        if(count($tUCWordsField)==0)
            return null;
        else
            return $tUCWordsField;
    }
    
    protected function GetHiddenField($tField) {
        $tHiddenField= array();
        $i = 0;
        while ($tField[$i]) {
            if (isset($this->mFieldHidden[$i])) {
                array_push($tHiddenField, $tField[$i][FieldName]);
                //$tCol.= "\t\t<td " . $tClass . " " . $tAlign . ">" . $tField[$i][FieldName] . "</td>\n";
            }
            $i++;
        }
        
        if(count($tHiddenField)==0)
            return null;
        else
            return $tHiddenField;
    }
    
    protected function GetUnhiddenField($tField) {
        $tUnhiddenField= array();
        $i = 0;
        while ($tField[$i]) {
            if (!isset($this->mFieldHidden[$i])) {
                array_push($tUnhiddenField, $tField[$i][FieldName]);
                //$tCol.= "\t\t<td " . $tClass . " " . $tAlign . ">" . $tField[$i][FieldName] . "</td>\n";
            }
            $i++;
        }
        
        if(count($tUnhiddenField)==0)
            return null;
        else
            return $tUnhiddenField;
    }

    
    private function GetSearchCategory($pValue) {
        if (!$this->mNotExecuteClass) {
            $tField = $this->mRawData->GetField();

            $tOption = '';
            $tSelect = '';

            $tSelect = "\n\t\t<select name=\"" . TEMPLATE_SETTING_SEARCH_CATEGORY_VAR . "\">\n";

            if ($pValue == "")
                $tSelected = "selected";
            $tOption = "\t\t\t<option value=\"\" " . $tSelected . ">" . TEMPLATE_SETTING_SEARCH_CATEGORY_DEFAULT_OPTION . "</option>\n";
            if (!empty($tField)) {
                $i = 0;
                while ($tField[$i]) {
                    $tSelected = "";
                    if ($i == $pValue && $pValue != "")
                        $tSelected = "selected";

                    $tOption.= "\t\t\t<option value=\"$i\" " . $tSelected . ">" . $tField[$i][FieldName] . "</option>\n";
                    $i++;
                }
            }

            $tSelect.= $tOption;
            $tSelect.= "\t\t</select>\n";

            return $tSelect;
        }
    }

    private function PrintSearchForm() {
        //GET: NILAI SEARCH JIKA ADA
        $tSearch = $this->GetSearch();
        $tValidation = new InputValidation();

        $tValidation->SetInput($_POST['fSearchKeywords']);
        $tValidation->SetPattern(pSearcKeywords);
        $tSearch['fKeywordsValue'] = $tValidation->CheckValidation();

        $tValidation->SetInput($_POST['fSearchCategory']);
        $tValidation->SetPattern(pUnsignedInt);
        $tSearch['fCategoryValue'] = $tValidation->CheckValidation();

        echo "\n\n<div id=\"Search-Form\"> \n";
        echo "<form name=\"formSearch\" action=\"" . $this->mCurrentURL . "\"> \n";
        echo "<table class=\"Search-Form Template-List\" align=\"center\" border=\"0\"> \n";

        echo "\t<tr>\n";
        echo "\t\t<td colspan=\"2\"><h2>" . strtoupper(TEMPLATE_SETTING_SEARCH_TITLE) . "</h2></td>\n";
        echo "\t</tr> \n";

        echo "\t<tr>\n";
        echo "\t\t<td class=\"caption\" width=\"\30%\">" . TEMPLATE_SETTING_SEARCH_CATEGORY_CAPTION . "</td>\n";
        echo "\t\t<td>";
        echo $this->GetSearchCategory($tSearch['fCategoryValue']);
        echo "\t\t</td>\n";
        echo "\t</tr> \n";

        echo "\t<tr> \n";
        echo "\t\t<td class=\"caption\">" . TEMPLATE_SETTING_SEARCH_KEYWORDS_CAPTION . "</td>\n";
        echo "\t\t<td><input type=\"text\" name=\"" . TEMPLATE_SETTING_SEARCH_KEYWORDS_VAR . "\" value=\"" . $tSearch['fKeywordsValue'] . "\" /></td> \n";
        echo "\t</tr> \n";

        echo "\t<tr> \n";
        echo "\t\t<td><input class=\"button\" type=\"button\" value=\"" . TEMPLATE_SETTING_RESET_BUTTON_CAPTION . "\" onclick=\"ResetSearchData()\" /></td>\n";
        echo "\t\t<td><input class=\"button\" type=\"button\" value=\"" . TEMPLATE_SETTING_SEARCH_BUTTON_CAPTION . "\" onclick=\"SearchData()\" /></td>\n";
        echo "\t</tr> \n";

        echo "</table> \n";
        echo "</form> \n";
        echo "</div> \n";
    }

    private function CreateFormExec() {
        $tPattern = pUnsignedInt;
        ($_POST['fId'] ? $fId = $_POST['fId'] : $fId = $_GET['fId']);
        $tValidation = new InputValidation($fId, $tPattern);
        $fId = $tValidation->CheckValidation();

        $tValidation->SetInput($_POST['fSearchKeywords']);
        $tValidation->SetPattern(pSearcKeywords);
        $tSearch['fKeywordsValue'] = $tValidation->CheckValidation();

        $tValidation->SetInput($_POST['fSearchCategory']);
        $tValidation->SetPattern(pUnsignedInt);
        $tSearch['fCategoryValue'] = $tValidation->CheckValidation();
        $fCurrentPage = $this->GetCurrentPage();

        echo "\n<form name=\"formExec\" method=\"post\" action=\"" . $this->mCurrentURL . "\">\n";
        echo "\t<input type=\"hidden\" name=\"fId\" value=\"" . $fId . "\" />\n";
        echo "\t<input type=\"hidden\" name=\"fAct\" value=\"\" />\n";

        //ADDITIONAL form exec
        if (count($this->mFieldSupport) > 0) {
            foreach ($this->mFieldSupport as $tKey => $tVal) {
                echo "\t<input type=\"hidden\" name=\"" . $tKey . "\" value=\"" . $tVal . "\" />\n";
            }
        }

        //SEARCH VALUE
        //CHECK: Jika terdapat Search maka tambahkan HIDDEN form untuk passing value
        if ($this->mIsSearchable) {
            echo "\t<input type=\"hidden\" name=\"" . TEMPLATE_SETTING_SEARCH_KEYWORDS_VAR . "\"  value=\"" . $tSearch['fKeywordsValue'] . "\"  />\n";
            echo "\t<input type=\"hidden\" name=\"" . TEMPLATE_SETTING_SEARCH_CATEGORY_VAR . "\" value=\"" . $tSearch['fCategoryValue'] . "\" />\n";
        }
        if ($this->mIsPageable)
            echo "\t<input type=\"hidden\" name=\"" . TEMPLATE_SETTING_PAGING_PAGE_VAR . "\" value=\"" . $fCurrentPage . "\" />\n";

        echo "</form>\n\n";
    }

    private function PrintPaging() {
        $fCurrentPage = $this->GetCurrentPage();
        $tSearch = $this->GetSearch();

        $tTotalRecord = ($this->mData->GetTotalRow() ? $this->mData->GetTotalRow() : $this->mData->Count());
        $url_target = '';

        $tMaxPage = $tTotalRecord / TEMPLATE_SETTING_LIST_PAGING_MAXIMUMPAGE;

        $i = 0;
        $found = false;
        while ($i <= count($tMaxPage)) {
            if (substr($tMaxPage, $i, 1) == ".")
                $found = true;
            if (!$found)
                $temp.=substr($tMaxPage, $i, 1);
            $i++;
        }

        if ($found)
            $tMaxPage = $temp;
        else {
            if ($tMaxPage == 0)
                $tMaxPage = 0;
            else
                $tMaxPage = $temp - 1;
        }

        //CEK: APAKAH NIAI SEARCH
        if ($search['keywords'] != '') {
            $url_target = '&s_keywords=' . $search['keywords'] . '&s_kategori=' . $search['category'];
        }

        if ($tMaxPage > 0) {
            //echo '<tr><td colspan="20" id="paging-container" align="center">';
            echo "\n\n<div class=\"Page-Container Template-List\" align=\"center\">\n";
            echo "  <div class=\"paging\" align=\"center\">\n";
            echo "  <ul>\n";
            echo "      <li onclick=\"FirstPage()\">" . TEMPLATE_SETTING_LIST_PAGING_FIRST_CAPTION . "</li>\n";

            //CEK: APAKAH HALAMAN POSISI DI AWAL, jika tidak tampilkan prev button
            if ($fCurrentPage != 0)
                echo "<li onclick=\"PrevPage()\"> < </li>\n";

            for ($i = 0; $i <= $tMaxPage; $i++) {
                if ($fCurrentPage == $i) //BILA PAGE AKTIF, JDKAN BKN LINK
                    echo "<li class=\"CurrentPage\"> " . ($i + 1) . " </li>";
                else
                    echo "<li onclick=\"GotoPage(" . $i . ")\"> " . ($i + 1) . " </li>\n";
            }


            //CEK: APAKAH HALAMAN POSISI DI AKHIR, jika tidak tampilkan next button
            if ($fCurrentPage < ($tMaxPage))
                echo "      <li onclick=\"NextPage()\"> > </li>\n";

            echo "      <li class='last' onclick=\"LastPage(" . $tMaxPage . ")\">" . TEMPLATE_SETTING_LIST_PAGING_LAST_CAPTION . "</li>\n";
            echo "  </ul>\n";
            echo "  </div>\n";
            echo "</div>\n\n";
        }
        //echo "</td></tr>";
    }

    protected function GetCurrentPage() {
        //VALIDASI CURRENT PAGE
        $fCurrentPage = $_POST[TEMPLATE_SETTING_PAGING_PAGE_VAR];
        $tPattern = pUnsignedInt;
        $tValidation = new InputValidation($fCurrentPage, $tPattern);
        $fCurrentPage = $tValidation->CheckValidation();

        if ($fCurrentPage)
            return $fCurrentPage;
        else
            return 0;
    }

    private function GetSearch() {
        $tResult = array();
        //VALIDASI CURRENT PAGE
        if ($_POST[TEMPLATE_SETTING_SEARCH_CATEGORY_VAR] && $_POST[TEMPLATE_SETTING_SEARCH_KEYWORDS_VAR]) {
            //VALIDASI HASIL SEARCH
            $tValidation = new InputValidation();

            $fCategoryValue = $_POST[TEMPLATE_SETTING_SEARCH_CATEGORY_VAR];
            $tValidation->SetInput($fCategoryValue);
            $tValidation->SetPattern(pUnsignedInt);
            $fCategoryValue = $tValidation->CheckValidation();
            $tResult['fCategoryValue'] = $fCategoryValue;

            $fKeywordsValue = $_POST[TEMPLATE_SETTING_SEARCH_KEYWORDS_VAR];
            $tValidation->SetInput($fKeywordsValue);
            $tValidation->SetPattern(pStringKeywords);
            $fKeywordsValue = $tValidation->CheckValidation();
            $tResult['fKeywordsValue'] = $fKeywordsValue;
            return $tResult;
        }
        else
            return false;
    }

    

    private function SetRowColor($pRowIndex) {
        //FUNGSI untuk menset warna zebra background pada list
        $tTemp = $pRowIndex / 2;
        if (substr($tTemp, -2, 1) == '.')
            $color = TEMPLATE_SETTING_LIST_ODD_BG;
        else
            $color = TEMPLATE_SETTING_LIST_EVEN_BG;

        return "bgcolor=\"" . $color . "\"";
    }

    private function PrintTitle() {
        if (!empty($this->mTitle)) {
            echo "<div class=\"Template-List\">";
            echo "<h1>$this->mTitle</h1>";
            echo "</div>";
        }
    }

    private function PrintSubtitle() {
        if (!empty($this->mSubtitle)) {
            echo "<div class=\"Template-List\">";
            echo "<h2>$this->mSubtitle</h2>";
            echo "</div>";
        }
    }

    
    
    

    private function CreateButton($pButton) {
        //check LEVEL LOGIN dengan BUTTON LEVEL AUTH
        $tFungsi= new Fungsi();
        $tIsAllow= $tFungsi->CheckAuthenticationAllow($pButton[Auth]);
        
        if ($tIsAllow) {
            switch ($pButton[Code]) {
                case 'add' : {
                        $tImg = TEMPLATE_IMAGES_PATH . 'button-add.png';
                        $tImg_alt = 'Add';
                        $tClass = "Add-Action";
                        break;
                    }
                case 'edt' : {
                        $tImg = TEMPLATE_IMAGES_PATH . 'button-edit.png';
                        $tImg_alt = 'Edit';
                        $tClass = "Edit-Action";
                        break;
                    }
                case 'del' : {
                        $tImg = TEMPLATE_IMAGES_PATH . 'button-delete.png';
                        $tImg_alt = 'Delete';
                        $tClass = "Delete-Action";
                        break;
                    }
                case 'dtl' : {
                        $tImg = TEMPLATE_IMAGES_PATH . 'button-detail.png';
                        $tImg_alt = 'Detail';
                        $tClass = "Detail-Action";
                        break;
                    }
                case 'rst' : {
                        $tImg = TEMPLATE_IMAGES_PATH . 'button-reset.png';
                        $tImg_alt = 'Reset Password';
                        $tClass = "Reset-Action";
                        break;
                    }
                case 'unl' : {
                        $tImg = TEMPLATE_IMAGES_PATH . 'button-unlock.png';
                        $tImg_alt = 'Unlock';
                        $tClass = "Unlock-Action";
                        break;
                    }
            }



            if (isset($pButton[Caption])) {
                $tOutput = "<input type=\"button\" class=\"button submit " . $tClass . "\" value=\" " . $pButton[Caption] . "\"  rel=\"" . $pButton[fIdValue] . "\" href=\"" . $pButton[Target] . "\" " . ($pButton[Event] ? "onclick=\"" . $pButton[Event] . "\"" : "") . " />";
            } else {
                $tOutput = "<img src=\"" . $tImg . "\" alt=\"" . $tImg_alt . "\" class=\"" . $tClass . "\" rel=\"" . $pButton[fIdValue] . "\" href=\"" . $pButton[Target] . "\" " . ($pButton[Event] ? "onclick=\"" . $pButton[Event] . "\"" : "") . " />";
            }
        }


        return $tOutput;
    }

    
    
    /* ========================================================================== */
    /* ========================================================================== */
    /*                      A U T H   S E T T I N G                               */
    /* ========================================================================== */
    // Nama var : $pAuthLevel 
    // Tipe var : INT
    // Def. val : NULL
    // Desc.    : Fungsi untuk melakukan set level autentikasi untuk object  untuk object yang ditentukan.
    //            Level autentikasi di deklarasi terlebih dahulu pada DB -> app_user_level
    //            nilai NULL artinya tidak diberikan autentikasi khusus.
    public function SetAddActionAuth($pAuthLevel) {
        $this->mAddAction[Auth] = $pAuthLevel;
    }

    public function SetEditActionAuth($pAuthLevel) {
        $this->mEditAction[Auth] = $pAuthLevel;
    }

    public function SetDeleteActionAuth($pAuthLevel) {
        $this->mDeleteAction[Auth] = $pAuthLevel;
    }

    public function SetDetailActionAuth($pAuthLevel) {
        $this->mDetailAction[Auth] = $pAuthLevel;
    }

    public function SetUnlockActionAuth($pAuthLevel) {
        $this->mUnlockAction[Auth] = $pAuthLevel;
    }

    public function SetResetActionAuth($pAuthLevel) {
        $this->mResetAction[Auth] = $pAuthLevel;
    }
    
    /* ========================================================================== */
    /*                   END : A U T H   S E T T I N G                            */
    /* ========================================================================== */
    /* ========================================================================== */

    
    /* ========================================================================== */
    /* ========================================================================== */
    /*               L I N K   T A R G E T   S E T T I N G                        */
    /* ========================================================================== */
    // Nama var : $pTargetURL
    // Tipe var : String
    // Def. val : NULL
    // Desc.    : Fungsi untuk melakukan set link target (URL) untuk object yang ditentukan.
    //            Jika nilai NULL maka tidak terdapat link target. 
    
    public function SetAddActionTarget($pTargetURL) {
        $this->mAddAction[Target] = $pTargetURL;
    }

    public function SetEditActionTarget($pTargetURL) {
        $this->mEditAction[Target] = $pTargetURL;
    }

    public function SetDeleteActionTarget($pTargetURL) {
        $this->mDeleteAction[Target] = $pTargetURL;
    }

    public function SetDetailActionTarget($pTargetURL) {
        $this->mDetailAction[Target] = $pTargetURL;
    }

    public function SetUnlockActionTarget($pTargetURL) {
        $this->mUnlockAction[Target] = $pTargetURL;
    }

    public function SetResetActionTarget($pTargetURL) {
        $this->mResetAction[Target] = $pTargetURL;
    }
    
    /* ========================================================================== */
    /*            END : L I N K   T A R G E T   S E T T I N G                     */
    /* ========================================================================== */
    /* ========================================================================== */
    
    
    
    /* ========================================================================== */
    /* ========================================================================== */
    /*                     E V E N T   A D D I T I O N                            */
    /* ========================================================================== */
    // Nama var : $pEvent
    // Tipe var : String
    // Def. val : NULL
    // Desc.    : Fungsi untuk melakukan penambahana event ONCLICK pada object yang ditentukan.

    public function SetAddActionEvent($pEvent) {
        $this->mAddAction[Event] = $pEvent;
    }

    public function SetEditActionEvent($pEvent) {
        $this->mEditAction[Event] = $pEvent;
    }

    public function SetDeleteActionEvent($pEvent) {
        $this->mDeleteAction[Event] = $pEvent;
    }

    public function SetDetailActionEvent($pEvent) {
        $this->mDetailAction[Event] = $pEvent;
    }

    public function SetUnlockActionEvent($pEvent) {
        $this->mUnlockAction[Event] = $pEvent;
    }

    public function SetResetActionEvent($pEvent) {
        $this->mResetAction[Event] = $pEvent;
    }
    
    /* ========================================================================== */
    /*                  END : E V E N T   A D D I T I O N                         */
    /* ========================================================================== */
    /* ========================================================================== */
    
    
    /* ========================================================================== */
    /* ========================================================================== */
    /*                    O U T P U T   S E T T I N G                             */
    /* ========================================================================== */
    
    public function SetTitle($pParams) {
        // Nama var : $pParams 
        // Tipe var : String
        // Desc.    : Fungsi untuk melakukan set nama judul dari List
        $this->mTitle = $pParams;
    }

    public function SetSubtitle($pParams) {
        // Nama var : $pParams 
        // Tipe var : String
        // Desc.    : Fungsi untuk melakukan set nama subjudul dari List
        $this->mSubtitle = $pParams;
    }
    
    public function SetFieldAlign($pAlign, $pIndex) {
        // Nama var : $pAlign 
        // Tipe var : String {"center", "left", "right"}
        // Desc.    : Fungsi untuk melakukan set alignment dari field
        $this->mFieldAlign[$pIndex] = $pAlign;
    }
    
    
    /* ========================================================================== */
    /*               O U T P U T   S E T T I N G : A C T I O N                    */
    /* ========================================================================== */
    public function SetAddActionCaption($pCaption) {
        $this->mAddAction[Caption] = $pCaption;
    }
    
    public function SetAddAction($pIsActivated) {
        // Nama var : $pParams 
        // Tipe var : String
        // Desc.    : Fungsi untuk melakukan set nama judul dari List
        $this->mAddAction = $pIsActivated;
    }

    public function SetTotalRecordDisplay($pIsShow) {
        $this->mIsTotalRecord = $pIsShow;
    }

    public function SetValiditasPattern($pValue) {
        $this->mValiditasPattern = $pValue;
    }

    public function SetFieldUCWords($pIndex) {
        $this->mFieldUCWords[$pIndex] = true;
    }

    public function SetFieldAddClass($pClass, $pIndex) {
        $this->mFieldClass[$pIndex] = $pClass;
    }

    public function SetFieldHidden($pIndex) {
        $this->mFieldHidden[$pIndex] = true;
    }

    public function SetCurrentURL($pParams) {
        //setiap pengesetan URL, lakukan RESET terlebih dahulu
        $temp = array();
        $this->mCurrentURL = $temp;

        $this->mCurrentURL = $pParams;
    }

    /* ========================================================================== */
    /*                END : O U T P U T   S E T T I N G                           */
    /* ========================================================================== */
    /* ========================================================================== */    
    
    
    /* ========================================================================== */
    /* ========================================================================== */
    /*                              P R I N T                                     */
    /* ========================================================================== */
    private function PrintActionButton($pId) {
        $tOutput = "";
        if ($pId != null) {
            //BUTTON DETAIL
            if ($this->mDetailAction[Auth]) {
                $this->mDetailAction[fIdValue] = $pId;
                $tOutput.= $this->CreateButton($this->mDetailAction);
            }

            //BUTTON UNLOCK
            if ($this->mUnlockAction[Auth]) {
                $this->mUnlockAction[fIdValue] = $pId;
                $tOutput.= $this->CreateButton($this->mUnlockAction);
            }

            //BUTTON RESET
            if ($this->mResetAction[Auth]) {
                $this->mResetAction[fIdValue] = $pId;
                $tOutput.= $this->CreateButton($this->mResetAction);
            }

            //BUTTON EDIT
            if ($this->mEditAction[Auth]) {
                $this->mEditAction[fIdValue] = $pId;
                $tOutput.= $this->CreateButton($this->mEditAction);
            }

            //BUTTON DELETE
            if ($this->mDeleteAction[Auth]) {
                $this->mDeleteAction[fIdValue] = $pId;
                $tOutput.= $this->CreateButton($this->mDeleteAction);
            }

            return $tOutput;
        } else {
            //ERROR: Nilai ID harus ada
        }
    }

    private function PrintParsingData($pJmlColDB) {
        //FUNGSI untuk memparse data dari QUERY dan diubah menjadi bentuk LIST sesuai TEMPLATE
        //CHECK: fika validitas field isset maka terdapat validatas field
        $tFungsi= new Fungsi();
        $tCurrentPage = $this->GetCurrentPage();
        $tJmlCol = $pJmlColDB;

        if ($this->mIsFieldNumber)
            $tJmlCol++;
        if ($this->mIsFieldAction)
            $tJmlCol++;

        try {
            $no = 1;
            $tContent = "";
            $i = 0;
            $tIndexFieldId = $this->mRawData->GetFieldIndexAsFieldId();
            while ($this->mData->MoveNext()) {
                $tValiditasData = true;
                $tClass = "";
                $tContentData = "";


                //FIELD NO
                if ($this->mIsFieldNumber)
                    $tContentData .= "\t<td align=\"center\">" . ($no + ($tCurrentPage * TEMPLATE_SETTING_LIST_PAGING_MAXIMUMPAGE) ) . ".</td>\n";

                //AMBIL NILAI INDEX FIELD UNTUK KEY VALUE, (biasanya merupakan PK)
                //PARSE FIELD DATA
                //Parse data dari Query DB
                for ($x = 0; $x < $pJmlColDB; $x++) {
                    $tOutput = $this->mData->GetRecord($i);
                    
                    //PK VALUE: SELAU DILETAKAN DI INDEX PERTAMA (0)
                    $tPKVal = $tOutput[0];

                    //CHECK: Is Validitas Field Exist?
                    if ($this->mValiditasField && $this->mValiditasPattern && $tValiditasData) {
                        //PERIKSA APAKAH URUTAN SESUAI DENGAN URUTAN FIELD VALIDITAS
                        //GET VALIDITAS VALUE
                        $tValiditas = $tFungsi->CheckValiditasPattern($this->mValiditasPattern, $tOutput);
                        $tValiditasDB = $tOutput[$this->mValiditasField];
                        //echo $tValiditas .' | '.$tValiditasDB.'<br>';
                        if ($tValiditas !== $tValiditasDB) {
                            $tValiditasData = false;
                        }

                        //VALIDITAS DEBUG
                        if ($this->mValiditasDebug)
                            echo 'RESULT: ' . $tValiditas . ' | DB: ' . $tValiditasDB . '<br>';
                    }

                    //CHECK: Is STATUS Field?
                    if (isset($this->mStatusField) && $this->mStatusField == $x) {
                        //echo $this->mStatusField.' | '.$x;
                        //PERIKSA APAKAH STATUS DIBLOCK KARENA TIDAK VALID
                        if (!$tValiditasData) {
                            $tValue = " DIBLOK ";
                            $tStatusClass = " Blocked ";
                        } else {
                            $tValue = $this->mStatus[$tOutput[$x]]['Caption'];
                            if ($this->mStatus[$tOutput[$x]]['Class'])
                                $tStatusClass = $this->mStatus[$tOutput[$x]]['Class'];
                            else
                                $tStatusClass = " Standard ";
                        }

                        //PERIKSA APAKAH TERDAPAT EVENT
                        $tStatusEvent = "";
                        if ($this->mStatus[$tOutput[$x]]['OnClick'])
                            $tStatusEvent.= " onclick=\"" . $this->mStatus[$tOutput[$x]]['OnClick'] . "\" ";

                        $tOutput[$x] = "<input type=\"button\" value=\"" . $tValue . "\" class=\"button Status " . $tStatusClass . "\" " . $tStatusEvent . " rel=\"" . $tPKVal . "\" />";
                    }


                    //CHECK: Is Align Setted?
                    $tAlign = "";
                    if ($this->mFieldAlign[$x]) {
                        $tAlign = ' align="' . $this->mFieldAlign[$x] . '" ';
                    }

                    //SET KEY VALUE DARI INDEX FIELD
                    if ($x == $tIndexFieldId) {
                        $tValueFieldId = $tOutput[$x];
                    }

                    //CHECK: Is Field Hidden?
                    if (!isset($this->mFieldHidden[$x])) {

                        //IF: kolom terakhir maka beri penanda class="LAST"
                        if ($x == ($pJmlColDB - 1))
                            $tContentData .= "\t<td $tAlign class=\"last " . ($this->mFieldClass[$x] ? $this->mFieldClass[$x] : "") . "\">";
                        else
                            $tContentData .= "\t<td $tAlign class=\"" . (!empty($this->mFieldClass[$x]) ? $this->mFieldClass[$x] : "") . "\">";

                        if ($this->mFieldUCWords[$x])
                            $tContentData .= ucwords(strtolower($tOutput[$x]));
                        else
                            $tContentData .= $tOutput[$x];

                        $tContentData .= "</td>\n";
                    }
                }
                //FIELD ACTION
                if ($this->mIsFieldAction) {
                    $tContentData .= "\t<td class=\"last ActionField\">" .
                            "<div class=\"Action-Container\">";
                    if ($tValiditasData) {
                        //JIKA VALIDATAS DATA = FALSE MAKA PENGOLAHAN DATA TIDAK DAPAT DILAKUKAN
                        $tContentData .= $this->PrintActionButton($tValueFieldId);
                    }

                    $tContentData .= "</div>" .
                            "</td>\n";
                }


                $tContent.= "<tr " . $this->SetRowColor($no) . " class=\"" . $tStatusClass . $tClass . "\">\n" . $tContentData . "</tr>\n";
                $no++;
                $i++;
            }

            if (empty($tContent)) {
                $tContent = "\t<tr><td colspan=\"" . ($tJmlCol - 1) . "\" class=\"NullData\">\n" .
                        "\t\t" . TEMPLATE_SETTING_LIST_DEFAULT_NULL;


                //FIELD ACTION
                if ($this->mIsFieldAction) {
                    $tContent .= "\t<td class=\"last ActionField\">" .
                            "<div class=\"Action-Container\">";

                    $tContent .= $this->PrintActionButton($tValueFieldId);

                    $tContent .= "</div>" .
                            "</td>\n";
                }
            }
        } catch (Exception $ex) {
            $tContent = "<tr><td colspan=\"" . ($tJmlCol - count($this->mFieldHidden) ) . "\">\n" .
                    "Exception Caught: " . $ex->getMessage() . "\n" .
                    "<p>Trace: " . $ex->getTraceAsString() . "</p> \n" .
                    "</td></tr>";
        }


        return $tContent;
    }

    
    private function PrintListData() {
        if (!$this->mNotExecuteClass) {
            $tCol = '';
            $tContent = '';
            $tJmlCol = 0; //JUMLAH TOTAL KESELURUHAN KOLOM
            $tJmlColDB = 0; //JUMLAH TOTAL KOLOM DARI DB
            $tField = $this->mRawData->GetField();
            $this->mData = $this->mRawData->ParseSQL($this->GetCurrentPage());

            //  PRINT HEADER LIST TABLE
            //////////////////////////////
            if ($this->mIsFieldNumber) {
                $tCol.= "\t\t<td>No.</td>\n";
                $tJmlCol++;
            }
            if (!empty($tField)) {
                $i = 0;
                while ($tField[$i]) {
                    $tClass = "";
                    //PERIKSA APAKAH MERUPAKAN KOLOM TERAKHIR
                    //Jika ya maka beri tanda untuk meenentukan class
                    if (!$tField[$i + 1])
                        $tClass = " class= \"last\"";

                    if (!isset($this->mFieldHidden[$i])) {
                        $tCol.= "\t\t<td " . $tClass . " " . $tAlign . ">" . $tField[$i][FieldName] . "</td>\n";
                    }

                    $i++;
                    $tJmlCol++;
                    $tJmlColDB++;
                }
            }
            if ($this->mIsFieldAction) {
                $tCol.= "\t\t<td class= \"last ActionField\">" .
                        "</td>\n";
                //$tJmlCol++;
            }

            if ($this->mIsFormExec)
                $this->CreateFormExec();

            $tTotalRow = ($this->mData->GetTotalRow() ? $this->mData->GetTotalRow() : $this->mData->Count());
            //if($mIsFieldAction)
            $tIsShowActionButton = (!empty($tTotalRow) && $this->mIsFieldAction ? true : false);

            echo "<div class=\"Template-List Container\">";

            //ERROR MESSAGE
            if (!empty($_POST[ERROR_SECTION]) && !empty($_POST[ERROR_CODE])) {
                $tErrorMsg = new ErrorMessage();
                $tErrorMsg->SetErrorCode($_POST[ERROR_CODE]);
                $tErrorMsg->SetErrorSection($_POST[ERROR_SECTION]);
                echo "<div class=\"ErrorMessage-Container\">" . $tErrorMsg->GetErrorMessage() . "</div>";
            }

            echo "<table class=\"List-Data Template-List\" cellspacing=\"0\" cellpaddding=\"0\" > \n";
            echo "\t<tr class=\"Row-Header-Border\"><td colspan=\"" . ($tJmlCol - count($this->mFieldHidden) ) . "\"></td>" .
            "<td>" . ($tIsShowActionButton ? "<div id=\"ActionButton-Container\" class=\"show\"></div>" : "") . "</td>" .
            "</tr>\n";
            echo "\t<tr class=\"Row-Header\">\n";
            echo $tCol;
            echo "\t<tr> \n";
            echo "\t<tr class=\"Row-Header-Border\">" .
            "<td colspan=\"" . ($tJmlCol - count($this->mFieldHidden) ) . "\"></td>" .
            "<td colspan=\"" . ($tJmlCol - count($this->mFieldHidden) ) . "\">" .
            "<div class=\"Action-Container top\"></div>" .
            "</td>" .
            "</tr>\n\n";


            echo $this->PrintParsingData($tJmlColDB);

            echo "\t<tr class=\"Row-Header-Border\">" .
            "<td colspan=\"" . ($tJmlCol - count($this->mFieldHidden) ) . "\"></td>" .
            "<td colspan=\"" . ($tJmlCol - count($this->mFieldHidden) ) . "\">" .
            "<div class=\"Action-Container bottom\"></div>" .
            "</td>" .
            "</tr>\n\n";

            if ($this->mIsTotalRecord) {
                echo "\t<tr><td colspan=\"" . (($tJmlCol + 1) - count($this->mFieldHidden) ) . "\" class=\"RemarksData\">\n" .
                "\t\t" . TEMPLATE_SETTING_LIST_TOTAL_RECORD . "= " . $tTotalRow
                .
                "\n\t</td></tr>\n";
            } else {
                echo "\t<tr><td colspan=\"" . (($tJmlCol + 1) - count($this->mFieldHidden) ) . "\" class=\"RemarksData\">\n" .
                "\n\t</td></tr>\n";
            }

            echo "</table>\n\n";

            // PAGING
            if ($this->mIsPageable)
                $this->PrintPaging();


            //BUTTON ADD
            if ($this->mAddAction[Auth] && $this->mIsFieldAction) {
                echo "<div id=\"AddAction-Container\">" . $this->CreateButton($this->mAddAction) . "</div>";
            }


            //MAKE UI DIALOG
            //DIALOG CONFIRM NEW TAB
            //JIKA ACTION = ENABLE (TRUE)
            if ($this->mIsFieldAction) {
                echo "<div id=\"dialog-ConfirmOpenNewTab\" title=\"" . TEMPLATE_SETTING_LIST_OPENTAB_TITLE . "\">" .
                TEMPLATE_SETTING_LIST_OPENTAB_MESSAGE .
                "</div>";

                //DIALOG CONFIRM DELETE
                echo "<div id=\"dialog-ConfirmDelete\" title=\"" . TEMPLATE_SETTING_LIST_DELETECONFIRM_TITLE . "\">" .
                TEMPLATE_SETTING_LIST_DELETECONFIRM_MESSAGE .
                "</div>";

                //DIALOG CONFIRM UNLOCK
                echo "<div id=\"dialog-ConfirmUnlock\" title=\"" . TEMPLATE_SETTING_LIST_UNLOCKCONFIRM_TITLE . "\">" .
                TEMPLATE_SETTING_LIST_UNLOCKCONFIRM_MESSAGE .
                "</div>";
                echo "</div>";

                //DIALOG CONFIRM RESET
                echo "<div id=\"dialog-ConfirmReset\" title=\"" . TEMPLATE_SETTING_LIST_RESETCONFIRM_TITLE . "\">" .
                TEMPLATE_SETTING_LIST_RESETCONFIRM_MESSAGE .
                "</div>";
            }
        }
    }
    
    public function PrintList() {
        echo '<div class="Template-List">';
        $this->PrintTitle();
        $this->PrintSubtitle();
        if ($this->mIsSearchable) {
            $this->PrintSearchForm();
        }
        if (!$this->mNotExecuteClass)
            $this->PrintListData();
        else {
            echo "<div class=\"ErrorMessage-Container\">\n" .
            "\t<div class=\"Title\">OUTPUT ERROR</div>\n" .
            "\t<div class=\"Content\">\n" .
            "\t\tAn error occurred, please try again. If the problem still occured, please contact Application Developer" .
            "\t</div>" .
            "</div>";
        }

        echo '</div>';
    }
    /* ========================================================================== */
    /*                           END : P R I N T                                  */
    /* ========================================================================== */
    /* ========================================================================== */

}